package rtssession

import (
	"log"
	"net"
	"time"

	"gitee.com/general252/gortc/pkg/format"
	"gitee.com/general252/gortc/pkg/rtcsdp"
	"gitee.com/general252/gortc/pkg/streammuxer"
	"gitee.com/general252/gortc/pkg/track"
	"github.com/pion/rtcp"
	"github.com/pion/rtp"
)

type ServerSessionPacket struct {
	mediaPath string
	mux       streammuxer.StreamMuxer
	writer    track.RtpRtcpWriter

	addr  net.Addr
	offer *rtcsdp.Session

	receiver *track.Receiver
	sender   *track.Sender

	pusher *streammuxer.Stream
	puller *streammuxer.Puller
}

func NewServerSessionPacket(mediaPath string, mux streammuxer.StreamMuxer, writer track.RtpRtcpWriter) *ServerSessionPacket {
	return &ServerSessionPacket{
		mediaPath: mediaPath,
		mux:       mux,
		writer:    writer,
	}
}

func (tis *ServerSessionPacket) Close(cause error) {

}

func (tis *ServerSessionPacket) OnOffer(offer *rtcsdp.Session) {
	tis.offer = offer

	for _, cm := range offer.Medias {
		if cm.Direction == rtcsdp.DirectionRecvOnly || cm.Direction == rtcsdp.DirectionSendRecv {
			for _, ct := range cm.Formats {
				tis._addReceiver(cm, ct)
			}
		}

		if cm.Direction == rtcsdp.DirectionSendOnly || cm.Direction == rtcsdp.DirectionSendRecv {
			for _, ct := range cm.Formats {
				tis._addSender(cm, ct)
			}
		}
	}
}

func (tis *ServerSessionPacket) _addReceiver(cm *rtcsdp.Media, ct format.Format) {
	writer := tis
	tis.receiver = track.NewReceiver(tis.mux, writer, cm, ct)

	var (
		puller   *streammuxer.Puller
		err      error
		streamId = streammuxer.NewStreamIdRTPOrder(cm.SSRC, ct.PayloadType())
	)

	// 有序的packet
	puller, err = tis.mux.AddPull(streamId, streammuxer.PullInfo{
		Name: "",
		OnPacket: func(info *streammuxer.StreamInfo, data *streammuxer.StreamData) {
			// 解包
			// 重新打包
		},
		OnStreamClose: func(stream *streammuxer.Stream) {
			_ = tis.mux.RemotePull(puller)
		},
	})
	if err != nil {
		log.Println(err)
		return
	}

	tis.puller = puller
}

func (tis *ServerSessionPacket) _addSender(cm *rtcsdp.Media, ct format.Format) {
	tis.sender = track.NewSender(tis.mux, tis.writer, cm, ct,
		func() (time.Time, bool) {
			return time.Time{}, false
		},
	)
}

// WriteRTP 实现接口 track.RtpRtcpWriter
func (tis *ServerSessionPacket) WriteRTP(pkt *rtp.Packet, addr net.Addr) error {
	return tis.writer.WriteRTP(pkt, tis.addr)
}

// WriteRTCP 实现接口 track.RtpRtcpWriter
func (tis *ServerSessionPacket) WriteRTCP(pkt []rtcp.Packet, addr net.Addr) error {
	return tis.writer.WriteRTCP(pkt, tis.addr)
}
